﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Runtime.Serialization;

namespace BrainTechLLC
{
    public interface ICanBeSelected
    {
        bool IsSelected { get; set; }
    }

    public interface IEventInfoWindowHandler
    {
        void OpenEventInfoWindow(object owner);
        void Close();
        bool IsOpen { get; }
    }

    public interface IKeyedOnProperty<T>
    {
        #region Properties

        T Key
        {
            get;
        }

        #endregion Properties
    }

#if NO_SILVERLIGHT
    [Browsable(true)]
    [TypeConverter(typeof(ExpandableObjectConverter))]
#endif
    public interface ILockable
    {
        void AquireLock();
        void ReleaseLock();
        bool Locked { get; }
        bool TryAquireLock();
    }

    public interface IMainWindow
    {
        double Left { get; set; }
        double Top { get; set; }
        double Width { get; set; }
        double Height { get; set; }
        double ActualWidth { get; }
        double ActualHeight { get; }
    }

    public interface IFollowInitializationSteps
    {
        void OnConstructor();
        void OnLoadAll();
        void OnLoadComplete();
        void OnApplySettings();
        void OnUISetup();
    }

#if NO_SILVERLIGHT
    [Browsable(true)]
    [TypeConverter(typeof(ExpandableObjectConverter))]
#endif
    public interface IMultipleItems<T>
    {
        List<T> AllItems { get; }
        T[] ArrayOfItems { get; }
    }

    /// <summary>
    /// Basic interface for a class with a lock object for multi-threaded synchronization
    /// </summary>
    public interface IObjectLock
    {
        object LockObject { get; }
    }

#if NO_SILVERLIGHT
    [Browsable(true)]
    [TypeConverter(typeof(ExpandableObjectConverter))]
#endif
    public interface IReadableAttribute
    {
        object Value { get; }
    }

    public static class CacheHelper
    {
    }

    /// <summary>
    /// Used on Properties
    /// This attribute specifies that the property is a Cache-derived object
    /// Used to auto-invalidate all cached properties in a single call
    /// </summary>
    [AttributeUsage(AttributeTargets.Property)]
    public class IsCached : System.Attribute
    {
        private bool _val;

        public IsCached(bool val)
        {
            _val = val;
        }

        public bool Cached
        {
            get { return _val; }
        }
    }

    [AttributeUsage(AttributeTargets.Method)]
    public class PopulatesProperty : System.Attribute
    {
        private string _val;

        public PopulatesProperty(string val)
        {
            _val = val;
        }

        public string PopulatesPropertyName
        {
            get { return _val; }
        }
    }

#if NO_SILVERLIGHT
    [Browsable(true)]
    [TypeConverter(typeof(ExpandableObjectConverter))]
#endif
    public interface IProvidesUniqueID
    {
        long UniqueID { get; set; }
    }

    public interface IHasId
    {
        int Id { get; set; }
    }

#if NO_SILVERLIGHT
    [Browsable(true)]
    [TypeConverter(typeof(ExpandableObjectConverter))]
#endif
    public interface ISupportsAdd<TListType>
    {
        bool Add(TListType item);
    }

#if NO_SILVERLIGHT
    [Browsable(true)]
    [TypeConverter(typeof(ExpandableObjectConverter))]
#endif
    public interface ISupportsAddByIndex<TIndex, TListType> where TListType : class
    {
        bool Add(TIndex key, TListType item);
    }

#if NO_SILVERLIGHT
    [Browsable(true)]
    [TypeConverter(typeof(ExpandableObjectConverter))]
#endif
    public interface ISupportsAddRemoveClear<TIndex, TListType> : ISupportsRemoveByIndex<TIndex, TListType>, ISupportsAddByIndex<TIndex, TListType>, ISupportsClear where TListType : class
    {
    }

#if NO_SILVERLIGHT
    [Browsable(true)]
    [TypeConverter(typeof(ExpandableObjectConverter))]
#endif
    public interface ISupportsAddRemoveClear<TListType> : ISupportsAdd<TListType>, ISupportsRemove<TListType>, ISupportsClear where TListType : class
    {
    }

#if NO_SILVERLIGHT
    [Browsable(true)]
    [TypeConverter(typeof(ExpandableObjectConverter))]
#endif
    public interface ISupportsClear
    {
        void Clear();
    }

#if NO_SILVERLIGHT
    [Browsable(true)]
    [TypeConverter(typeof(ExpandableObjectConverter))]
#endif
    public interface ISupportsCount
    {
        int Count { get; }
    }

#if NO_SILVERLIGHT
    [Browsable(true)]
    [TypeConverter(typeof(ExpandableObjectConverter))]
#endif
    public interface ISupportsEnqueueDequeue<TListType>
    {
        int Enqueue(TListType item);
        bool Dequeue(out TListType item);
    }

#if NO_SILVERLIGHT
    [Browsable(true)]
    [TypeConverter(typeof(ExpandableObjectConverter))]
#endif
    public interface ISupportsFind<TIndex, TListType> where TListType : class
    {
        TListType Find(TIndex key);
    }

#if NO_SILVERLIGHT
    [Browsable(true)]
    [TypeConverter(typeof(ExpandableObjectConverter))]
#endif
    public interface ISupportsFindMany<TIndex, TListType> : ISupportsFindSingle<TIndex, TListType> where TListType : class
    {
        List<TListType> Find(TIndex key);
    }

#if NO_SILVERLIGHT
    [Browsable(true)]
    [TypeConverter(typeof(ExpandableObjectConverter))]
#endif
    public interface ISupportsFindSingle<TIndex, TListType> where TListType : class
    {
        TListType FindSingle(TIndex key);
    }

#if NO_SILVERLIGHT
    [Browsable(true)]
    [TypeConverter(typeof(ExpandableObjectConverter))]
#endif
    public interface ISupportsRemove<TKeyType>
    {
        bool Remove(TKeyType key);
    }

#if NO_SILVERLIGHT
    [Browsable(true)]
    [TypeConverter(typeof(ExpandableObjectConverter))]
#endif
    public interface ISupportsRemoveByIndex<TIndex, TListType> where TListType : class
    {
        bool Remove(TIndex key, TListType item);
    }

    public interface IWatcherNotifiable
    {
        void AddByFileName(string s);
        void RemoveByFileName(string s);
        void FileNameChanged(string oldFileName, string newFileName);
    }

    [DataContract]
    public enum LogSeverity
    {
        [EnumMember]
        DebugInformation = 0,
        [EnumMember]
        DebugWarning = 1,
        [EnumMember]
        DebugError = 2,
        [EnumMember]
        DebugCritical = 3,
        [EnumMember]
        Information = 4,
        [EnumMember]
        Warning = 5,
        [EnumMember]
        Error = 6,
        [EnumMember]
        Critical = 7,
        [EnumMember]
        Max = 8
    }

#if NO_SILVERLIGHT
    [Browsable(true)]
    [TypeConverter(typeof(ExpandableObjectConverter))]
#endif
    public interface ILogger
    {
        event EventHandler<ObjectEventArgs<LogMessage>> LoggedMessage;
        bool AddLogListener(ILogListener listener);
        bool RemoveLogListener(ILogListener listener);
        void Log(string messageType, string message, LogSeverity severity);
        void Log(Exception ex, LogSeverity severity, bool verbose);
        void Log(Exception ex, string message, LogSeverity severity, bool verbose);
        void Log(LogMessage message);
        void SetFilter(LogSeverity severity, bool logThisSeverityLevel);

        bool WantExit { get; set; }
        void BeginLogging();
        LogSeverity LogFilter { get; }
    }

    [DataContract]
    [Serializable]
    public class LogMessage
    {
        [DataMember]
        public DateTime LogTime { get; set; }

        [DataMember]
        public string Message { get; set; }

        [DataMember]
        public LogSeverity Severity { get; set; }

        [DataMember]
        public string MessageType { get; set; }

        public override string ToString()
        {
            return FormatLogEntry(LogTime.ToString(), MessageType, Message, Severity);
        }

        public string FormatLogEntry(string nowString, string messageType, string message, LogSeverity severity)
        {
            StringBuilder sb = new StringBuilder(256);
            sb.Append(nowString);
            sb.Append(',');
            sb.Append(messageType);
            sb.Append(',');
            sb.Append(severity.ToString());
            sb.Append(',');
            sb.Append(message);
            return sb.ToString();
        }
    }

    public interface ILogListener
    {
        #region Events

        event EventHandler<SimpleEventArgs<LogMessage>> NewLogEntry;

        #endregion Events

        #region Properties

        bool IsListening
        {
            get;
            set;
        }

        #endregion Properties

        #region Methods

        void OnNewLogEntry(SimpleEventArgs<LogMessage> eventArgs);

        #endregion Methods
    }

    public class SimpleEventArgs<T> : EventArgs
    {
        #region Constructors

        public SimpleEventArgs(T val)
        {
            Value = val;
        }

        public SimpleEventArgs()
        {
        }

        #endregion Constructors

        #region Properties

        public T Value
        {
            get;
            set;
        }

        #endregion Properties
    }

    /// <summary>
    /// Basic Generic Cache interface
    /// </summary>
    public interface ICacheBase<T>
    {
        #region Methods

        T GetItem();

        T GetItem(object populateCacheParameter, params object[] args);

        bool IsCacheValid();

        bool IsCacheValid(object populateCacheParameter);

        #endregion Methods
    }

    // TODO - move to better home
    public interface ICanSaveAndRestore : IHasChanged
    {
        void PerformPostRestoreSetup();
        bool Restore<T>(List<object> arguments, out T restored) where T : class;
        void Save(List<object> arguments);
    }

    public interface IHasChanged
    {
        DateTime LastChanged { get; set; }
        DateTime LastSaved { get; set; }
        void MarkChanged();
        void MarkRestored();
        void MarkSaved();
    }
}
